using System.Collections.Generic;

namespace Framework
{
    public class BTreeScheduler : MonoSingleton<BTreeScheduler>
    {
        private List<IBehaviorTree> _treeList = new List<IBehaviorTree>();
        private List<int> _toRemoveIndexList = new List<int>();
        private bool _isLock = false;

        public void StartTree(IBehaviorTree tree)
        {
            _treeList.Add(tree);
        }

        public void StopTree(IBehaviorTree tree)
        {
            int index = _treeList.IndexOf(tree);
            if (index > -1)
            {
                StopTreeByIndex(index);
            }
        }

        public void StopAllTree()
        {
            int count = _treeList.Count;
            for (int i = 0; i < count; ++i)
            {
                _treeList[i].Dispose();
            }
            _treeList.Clear();
            _toRemoveIndexList.Clear();
        }

        public void Update()
        {
            int count = _treeList.Count;
            if (count > 0)
            {
                _isLock = true;
                for (int i = 0; i < count; ++i)
                {
                    if (_toRemoveIndexList.IndexOf(i) == -1)
                    {
                        TaskStatus status = _treeList[i].Tick();
                        if (status != TaskStatus.Running)
                        {
                            _toRemoveIndexList.Add(i);
                        }
                    }
                }
                _isLock = false;
                count = _toRemoveIndexList.Count;
                if (count > 0)
                {
                    _toRemoveIndexList.Sort();
                    for (int i = count - 1; i >= 0; --i)
                    {
                        StopTreeByIndex(_toRemoveIndexList[i]);
                    }
                    _toRemoveIndexList.Clear();
                }
            }
        }

        private void StopTreeByIndex(int index)
        {
            if (_isLock)
            {
                _toRemoveIndexList.Add(index);
            }
            else
            {
                IBehaviorTree tree = _treeList[index];
                _treeList.RemoveAt(index);
                tree.Dispose();
            }
        }
    }
}